package org.richin.collection.util;

import java.lang.reflect.Array;
import java.util.*;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;

import org.richin.array.util.ArrayUtils;
import org.richin.lang.util.ObjectUtils;
import org.richin.system.util.Assert;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class CollectionUtils extends org.apache.commons.collections.CollectionUtils {
	public static <T> T first(Collection<T> p_collection) throws IllegalArgumentException {
		if (sizeOf(p_collection) == 0) {
			throw new IllegalArgumentException("Collection must not be null or empty.");
		}
		return p_collection.iterator().next();
	}
	   /**
     * 取两个有相同元素类型的 {@code java.util.Set} 的交集，即公共部份的新的 {@code java.util.Set}。
     * <ul>
     * <li>{@code setA == null && setB == null} --&gt; 返回 {@code null}。</li>
     * <li>{@code setA != null && setB == null} --&gt; 返回 {@code null}。</li>
     * <li>{@code setA == null && setB != null} --&gt; 返回 {@code null}。</li>
     * <li>{@code setA != null && setB != null} --&gt; 返回 {@code setA} 和 {@code setB} 的交集。</li>
     * </ul>
     *
     * @param <T> {@code Set} 中保存的对象。
     * @param setA 第一个 {@code Set}。
     * @param setB 第二个 {@code Set}。
     * @return {@code setA} 和 {@code setB} 的交集。
     */
    public static <T> Set<T> intersectHashSet(Set<T> setA, Set<T> setB) {
        boolean isEmptySetA = isEmpty(setA);
        boolean isEmptySetB = isEmpty(setB);
        if (isEmptySetA || isEmptySetB)
            return null;
        Set<T> result = getHashSet(setA);
        result.retainAll(setB);
        return result;
    }

    /**
     * 移除 {@code setA} 中那些包含在 {@code setB} 中的元素。<br />
     * 此方法不会修改 {@code setA}，只是复制一份作相应操作，返回的是全新的 {@code Set} 对象。
     * <ul>
     * <li>{@code setA == null} --&gt; 返回 {@code null}。</li>
     * <li>{@code setB == null} --&gt; 返回 {@code setA}。</li>
     * <li>{@code setA != null && setB != null} --&gt; 返回 {@code setA} 和 {@code setB} 的不对称差集。</li>
     * </ul>
     *
     * @param <T> {@code Set} 中保存的对象。
     * @param setA 第一个 {@code Set}。
     * @param setB 第二个 {@code Set}。
     * @return {@code setA} 和 {@code setB} 的不对称差集。
     */
    public static <T> Set<T> differenceHashSet(Set<T> setA, Set<T> setB) {
        boolean isEmptySetA = isEmpty(setA);
        boolean isEmptySetB = isEmpty(setB);
        if (isEmptySetA)
            return null;
        if (isEmptySetB)
            return setA;
        Set<T> result = getHashSet(setA);
        result.removeAll(setB);
        return result;
    }

    /**
     * 取两个有相同元素类型的 {@code java.util.Set} 的补集。
     *
     * @param <T> {@code Set} 中保存的对象。
     * @param setA 第一个 {@code Set}。
     * @param setB 第二个 {@code Set}。
     * @return {@code setA} 和 {@code setB} 的补集。
     */
    public static <T> Set<T> complementHashSet(Set<T> setA, Set<T> setB) {
        return differenceHashSet(unionHashSet(setA, setB), intersectHashSet(setA, setB));
    }

	@Nonnull
    public static <T> T[] toArray(@Nonnull final Iterator<T> itor, @Nonnull final Class<? extends T[]> newType) {
        List<T> list = toList(itor);
        return ArrayUtils.toArray(list, newType);
    }
    /**
     * 合并两个有相同元素类型的 {@code java.util.Set}。
     * <ul>
     * <li>{@code setA == null && setB == null} --&gt; 返回 {@link #getHashSet()}。</li>
     * <li>{@code setA != null && setB == null} --&gt; 返回 {@code setA}。</li>
     * <li>{@code setA == null && setB != null} --&gt; 返回 {@code setB}。</li>
     * <li>{@code setA != null && setB != null} --&gt; 返回 {@code setA} 和 {@code setB} 的并集。</li>
     * </ul>
     *
     * @param <T> {@code Set} 中保存的对象。
     * @param setA 第一个 {@code Set}。
     * @param setB 第二个 {@code Set}。
     * @return {@code setA} 和 {@code setB} 的并集。
     */
    public static <T> Set<T> unionHashSet(Set<T> setA, Set<T> setB) {
        boolean isEmptySetA = isEmpty(setA);
        boolean isEmptySetB = isEmpty(setB);
        if (isEmptySetA && isEmptySetB)
            return getHashSet();
        if (isEmptySetA && !isEmptySetB)
            return setB;
        if (!isEmptySetA && isEmptySetB)
            return setA;
        Set<T> result = getHashSet(setA);
        result.addAll(setB);
        return result;
    }

    /**
     * 用该方法来代替 {@code new HashMap<K, V>()} 方式获得新的 {@code java.util.Map} 的实例对象。
     *
     * @param <K> {@code Map} 中的键对象。
     * @param <V> {@code Map} 中的值对象。
     * @return {@code java.util.Map<K, V>} 关于 {@code java.util.HashMap<K, V>} 实现的新实例。
     */
    public static <K, V> Map<K, V> getMap() {
        return new HashMap<K, V>();
    }

    /**
     * 用该方法来代替 {@code new LinkedHashMap<K, V>()} 方式获得新的 {@code java.util.Map} 的实例对象。
     *
     * @param <K> {@code Map} 中的键对象。
     * @param <V> {@code Map} 中的值对象。
     * @return {@code java.util.Map<K, V>} 关于 {@code java.util.LinkedHashMap<K, V>} 实现的新实例。
     */
    public static <K, V> Map<K, V> getLinkedMap() {
        return new LinkedHashMap<K, V>();
    }

    /**
     * 用该方法来代替 {@code new ArrayList<T>()} 方式获得新的 {@code java.util.List} 的实例对象。
     *
     * @param <T> {@code List<T>} 中保存的对象。
     * @return {@code java.util.List<T>} 关于 {@code java.util.ArrayList<T>} 实现的新实例。
     */
    public static <T> List<T> getList() {
        return new ArrayList<T>();
    }

    /**
     * 用该方法来代替 {@code new ArrayList<T>()} 方式获得新的 {@code java.util.List} 的实例对象。
     *
     * @param <T> {@code List<T>} 中保存的对象。
     * @param c 其中的元素将存放在新的 {@code list} 中的 {@code collection}。
     * @return {@code java.util.List<T>} 关于 {@code java.util.ArrayList<T>} 实现的新实例。
     */
    public static <T> List<T> getList(Collection<? extends T> c) {
        if (isNotEmpty(c))
            return new ArrayList<T>(c);
        return new ArrayList<T>();
    }

    /**
     * 用该方法来代替 {@code new LinkedList<T>()} 方式获得新的 {@code java.util.List} 的实例对象。
     *
     * @param <T> {@code List<T>} 中保存的对象。
     * @return {@code java.util.List<T>} 关于 {@code java.util.LinkedList<T>} 实现的新实例。
     */
    public static <T> List<T> getLinkedList() {
        return new LinkedList<T>();
    }

    /**
     * 用该方法来代替 {@code new HashSet<T>()} 方式获得新的 {@code java.util.Set} 的实例对象。
     *
     * @param <T> {@code Set<T>} 中保存的对象。
     * @return {@code java.util.Set<T>} 关于 {@code java.util.HashSet<T>} 实现的新实例。
     */
    public static <T> Set<T> getHashSet() {
        return new HashSet<T>();
    }

    /**
     * 用该方法来代替 {@code new HashSet<T>(Collection<? extends T> c)} 方式获得新的 {@code java.util.Set} 的实例对象。
     *
     * @param <T> {@code Set} 中保存的对象。
     * @param c 其中的元素将存放在新的 {@code set} 中的 {@code collection}。
     * @return {@code java.util.Set<T>} 关于 {@code java.util.HashSet<T>} 实现的新实例。
     */
    public static <T> Set<T> getHashSet(Collection<? extends T> c) {
        if (isEmpty(c))
            return new HashSet<T>();
        return new HashSet<T>(c);
    }

    /**
     * 用该方法来代替 {@code new LinkedList<E>()} 方式获得新的 {@code java.util.Queue} 的实例对象。
     *
     * @param <E> {@code Queue<E>} 中保存的对象。
     * @return {@code java.util.Queue<E>} 关于 {@code java.util.LinkedList<E>} 实现的新实例。
     */
    public static <E> Queue<E> getQueue() {
        return new LinkedList<E>();
    }

	public static List arrayToList(Object source) {
		return Arrays.asList(ObjectUtils.toObjectArray(source));
	}
	public static void mergePropertiesIntoMap(Properties props, Map map) {
		if (map == null)
			throw new IllegalArgumentException("Map must not be null");
		if (props != null) {
			String key;
			for (Enumeration en = props.propertyNames(); en.hasMoreElements(); map.put(key, props.getProperty(key)))
				key = (String) en.nextElement();

		}
	}


    @Nonnull
    public static <T> List<T> toList(@Nonnull Iterator<T> itor) {
        return toList(itor, 12);
    }

    @Nonnull
    public static <T> List<T> toList(@Nonnull Iterator<T> itor, @Nonnegative int estimatedSize) {
        final List<T> list = new ArrayList<T>(estimatedSize);
        addToList(itor, list);
        return list;
    }

    public static <T> List<T> toListUnique(@Nonnull Iterator<T> itor) {
        final List<T> list = new ArrayList<T>(32);
        final Set<T> set = new HashSet<T>(32);
        while(itor.hasNext()) {
            final T e = itor.next();
            if(set.add(e)) {
                list.add(e);
            }
        }
        return list;
    }

    @Nonnull
    public static <T> Set<T> toSet(@Nonnull Iterator<T> itor) {
        final Set<T> set = new LinkedHashSet<T>();
        while(itor.hasNext()) {
            set.add(itor.next());
        }
        return set;
    }

    @SuppressWarnings("unchecked")
    public static void addToList(@Nonnull Iterator itor, @Nonnull List list) {
        while(itor.hasNext()) {
            list.add(itor.next());
        }
    }

    public static int count(@Nonnull Iterator<?> itor) {
        int sum = 0;
        while(itor.hasNext()) {
            sum++;
            itor.next();
        }
        return sum;
    }
    public static <E> int count(@Nonnull Collection<E> coll,E e) {
    	if(isEmpty(coll))
    		return 0;
    	int sum = 0;
    	for(Iterator<E> it=coll.iterator();it.hasNext();)
    		if(ObjectUtils.nullSafeEquals(it.next(), e))
    			sum++;
		return sum;
    }

    public static void main(String[] args) {
		List<String> list=new ArrayList<String>();
		list.add("");
		list.add("a");
		list.add("s");
		list.add("4");
		list.add("5");
		list.add("d");
		list.add("");
		list.add("");
		list.add(null);
		list.add(null);
		list.add("");
		//list.add());
		//org.apache.commons.lang.ArrayUtils
		//toPlatArray(list);
		//System.out.println(ArrayUtils.toString((toArray(list))));
	//	System.out.println(count(list));
		//System.out.println(max(list));
	}
	/**
	 * Returns the initial of a collection, that is, all elements except the last.
	 * @param p_collection the collection for which to return the initial part.
	 * @return all elements of the collection except the last, or an empty list if
	 * the specified collection is empty.
	 */
	public static <T> List<T> init(Collection<T> p_collection) {
		if (sizeOf(p_collection) == 0) {
			return Collections.emptyList();
		}
		int last = p_collection.size() - 1;
		List<T> list = new ArrayList<T>(p_collection);
		list.remove(last);
		return list;
	}

	/**
	 * Returns the tail of a collection, that is, all elements except the first.
	 * @param p_collection the collection for which to return the tail.
	 * @return all elements of the collection except the first, or an empty list if
	 * the specified collection is empty.
	 */
	public static <T> List<T> tail(Collection<T> p_collection) {
		if (sizeOf(p_collection) == 0) {
			return Collections.emptyList();
		}
		List<T> list = new ArrayList<T>(p_collection);
		list.remove(0);
		return list;
	}

	/**
	 * Returns the last element of a collection.
	 * @param p_collection the list for which to return the last element.
	 * @return the last element of the collection.
	 * @throws Exception 
	 * @exception FunctionException thrown if the collection is <code>null</code> or
	 * empty.
	 */
	public static <T> T last(Collection<T> p_collection) throws Exception {
		int size = sizeOf(p_collection);
		if (size == 0) {
			throw new Exception("Collection must not be null or empty.");
		}
		Iterator<T> iter = p_collection.iterator();
		for (int i = 1; i < size; i++) {
			iter.next();
		}
		return iter.next();
	}

	public final static <T> T GetFirstEntry(Collection<T> collection) {
		if (isEmpty(collection))
			return null;
		return collection.iterator().next();
	}

	/**
	 * Returns the size of a collection, returning zero if the list is
	 * <code>null</code>.
	 *
	 * @param p_collection the collection for which to return the size.
	 * @return the size of the collection, or <code>0</code> if the collection is
	 * <code>null</code>.
	 */
	public static int sizeOf(Collection<?> p_collection) {
		if (p_collection == null) {
			return 0;
		}
		return p_collection.size();
	}

	@SuppressWarnings("unchecked")
	public static <T> Collection<T> addToCollection(Collection<T> col, T... array) {
		int size = Array.getLength(array);
		for (int iter = 0; iter < size; iter++) {
			col.add((T) Array.get(array, iter));
		}
		return col;
	}

	public static <T> String concat(Collection<T> collection, String separator) {
		StringBuffer sb = new StringBuffer(collection.size() * 4);
		String s = "";

		for (T item : collection) {
			sb.append(s);
			sb.append(item.toString());
			s = separator;
		}
		return sb.toString();
	}

	public static <T> T[] toArray(Collection<T> collection) {

		T[] outerArray = (T[])Array.newInstance(Object[].class, collection.size());

		int i = 0;
		for (Iterator<T> iter = collection.iterator(); iter.hasNext();) {
			T element =iter.next();
			if (element instanceof Collection) {
				Array.set(outerArray, i++, toPlatArray((Collection) element));
			}
			else
				Array.set(outerArray, i++, element);
		}

		return outerArray;
	}

	static public <T> void removeNulls(Collection<T> list) {
		for (Iterator<T> iter = list.iterator(); iter.hasNext();) {
			Object e = iter.next();
			if (e == null)
				iter.remove();
		}
	}

	@SuppressWarnings("unchecked")
	public static boolean isCollection(Class theClass) {
		return Collection.class.isAssignableFrom(theClass);
	}

	@SuppressWarnings("unchecked")
	public static boolean isMap(Class theClass) {
		return Map.class.isAssignableFrom(theClass);
	}

	@SuppressWarnings("unchecked")
	private static Object toPlatArray(Collection collection) {
		Object firstElement = collection.iterator().next();
		Object array = Array.newInstance(firstElement.getClass(), collection.size());
		int i = 0;
		for (Iterator iter = collection.iterator(); iter.hasNext();) {
			Object element = iter.next();
			Array.set(array, i++, element);
		}

		return array;
	}


	/**
	 * Given an array, creates a Set with the items of that Array
	 *
	 * @param <T> the type of the objects in the array
	 * @param array
	 * @return
	 */
	public static <T> Set<T> createSetFromArray(T[] array) {
		Set<T> set = new HashSet<T>();
		for (T o : array) {
			set.add(o);
		}
		return set;
	}

	/**
	*
	* 取Collection和Remove的差集
	* <br/>
	* - 功能和CollectionUtils.removeAll的文档描述一样，但是CollectionUtils的removeAll有个Bug
	*
	* @param collection
	*            - the collection from which items are removed (in the returned
	*            collection)
	* @param remove
	*            - the items to be removed from the returned collection
	* @return a Collection containing all the elements of collection except any
	*         elements that also occur in remove.
	*/
	public static <T> Collection<T> removeAll(Collection<T> collection, Collection<T> remove) {
		Collection<T> result = new ArrayList<T>();
		Iterator<T> e = collection.iterator();
		while (e.hasNext()) {
			T oneInCollection = e.next();
			if (!remove.contains(oneInCollection)) {
				result.add(oneInCollection);
			}
		}
		return result;
	}

	/**
	 * 移除collection里面的重复元素
	 *
	 * @param collection
	 *  - the collection which may contain duplicated items
	 * @return
	 * a Collection containing all the unduplicated elements of collection
	 */
	public static <T> Collection<T> removeDuplicates(Collection<T> collection) {
		Collection<T> result = new ArrayList<T>();
		Iterator<T> e = collection.iterator();
		while (e.hasNext()) {
			T oneInCollection = e.next();
			if (!result.contains(oneInCollection)) {
				result.add(oneInCollection);
			}
		}
		return result;
	}

	public static <T> Collection<T> nonNullCollection(final Collection<T> collection) {
		if (collection == null) {
			return Collections.emptySet();
		}

		return collection;
	}

	/**
	 * Returns true, if the c1 contains any element of c2 (using {@link Collection#contains}.
	 *
	 * @param c1   The containing collection.
	 * @param c2   The contained collection.
	 * @return     True, if c1 contains at least one element of c2, false otherwise.
	 */
	public static <T> boolean containsAny(Collection<T> c1, Collection<T> c2) {
		Iterator<T> i = c2.iterator();
		while (i.hasNext()) {
			if (c1.contains(i.next())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Adds all elements in the collection <code>toBeAdded</code> that are
	 * not yet member of the collection <code>c</code> to <code>c</code>.
	 *
	 * @param c                The collection to that the objects are added.
	 * @param toBeAdded        The collection containing the objects to be added.
	 */
	public static <T> void union(Collection<T> c, Collection<T> toBeAdded) {
		for (Iterator<T> iterator = toBeAdded.iterator(); iterator.hasNext();) {
			T o = iterator.next();
			if (!c.contains(o))
				c.add(o);
		}
	}

	public static <T> Collection<T> add(T item, Collection<T> collection) {
		collection.add(item);
		return collection;
	}

	public static <T> Collection<T> remove(T item, Collection<T> collection) {
		collection.remove(item);
		return collection;
	}

	public static <T> Iterator<T> concatenate(final Iterator<T> a, final Iterator<T> b) {
		return new Iterator<T>() {
			private Iterator<T> currentIterator = a;

			public void remove() {
				throw new UnsupportedOperationException();
			}

			private Iterator<T> getCurrentIterator() {
				if (currentIterator == a && !a.hasNext()) {
					currentIterator = b;
				}
				return currentIterator;
			}

			public boolean hasNext() {
				return getCurrentIterator().hasNext();
			}

			public T next() {
				return getCurrentIterator().next();
			}
		};
	}

	public static <T> T firstOrNull(Collection<T> collection) {
		return isNotEmpty(collection) ? collection.iterator().next() : null;
	}

	public static boolean isCollection(Object value) {
		return value instanceof Collection || value instanceof Map || value instanceof Iterator
				|| (value != null && value.getClass().isArray());
	}

	@SuppressWarnings("unchecked")
	public static Iterator iterator(Object value) {
		if (value == null) {
			return Collections.EMPTY_LIST.iterator();
		} else if (value instanceof Collection) {
			Collection collection = (Collection) value;
			return collection.iterator();
		} else if (value.getClass().isArray()) {
			// TODO we should handle primitive array types?
			List<Object> list = Arrays.asList((Object[]) value);
			return list.iterator();
		} else if (value instanceof NodeList) {
			// lets iterate through DOM results after performing XPaths
			final NodeList nodeList = (NodeList) value;
			return new Iterator<Node>() {
				int idx = -1;

				public boolean hasNext() {
					return ++idx < nodeList.getLength();
				}

				public Node next() {
					return nodeList.item(idx);
				}

				public void remove() {
					throw new UnsupportedOperationException();
				}
			};
		} else {
			return Collections.singletonList(value).iterator();
		}
	}

	public static <E> List<E> toList(Collection<E> collection) {
		List<E> resultList = new ArrayList<E>(collection.size());
		resultList.addAll(collection);
		return resultList;
	}

/*	public static <E> List<E> toList(Iterator<E> it) {
		List<E> resultList = new ArrayList<E>();
		while (it.hasNext()) {
			resultList.add(it.next());
		}
		return resultList;
	}*/
    public static <T> T getFirst(final Collection<T> col) {
        for(T e : col) {
            return e;
        }
        return null;
    }
	public static boolean isEmpty(Map<?,?> map) {
		return (map == null || map.isEmpty());
	}
	public static void mergeArrayIntoCollection(Object array, Collection<Object> collection) {
		Assert.notNull(collection,"Collection must not be null");
		Object[] arr = ObjectUtils.toObjectArray(array);
		for (Object elem : arr) {
			collection.add(elem);
		}
	}
	/**
	 * 将数组元素全部加到一个集合中。<BR>
	 *
	 * Add all the elements to a collection<BBR>
	 *
	 * @param r_Collection
	 * @param r_Objects
	 */
	public static void addAll(final Collection r_Collection,
			final Object[] r_Objects) {
		if (null == r_Objects) {
			return;
		}

		for (int i = 0; i < r_Objects.length; i++) {
			if (null != r_Objects[i]) {
				r_Collection.add(r_Objects[i]);
			}
		}
	}

	/**
	 * Check whether the given Iterator contains the given element.
	 * @param iterator the Iterator to check
	 * @param element the element to look for
	 * @return <code>true</code> if found, <code>false</code> else
	 */
	public static boolean contains(Iterator<?> iterator, Object element) {
		if (iterator != null) {
			while (iterator.hasNext()) {
				Object candidate = iterator.next();
				if (ObjectUtils.nullSafeEquals(candidate, element)) {
					return true;
				}
			}
		}
		return false;
	}
	public static Object findFirstMatch(Collection source, Collection candidates) {
		if (isEmpty(source) || isEmpty(candidates))
			return null;
		for (Iterator it = candidates.iterator(); it.hasNext();) {
			Object candidate = it.next();
			if (source.contains(candidate))
				return candidate;
		}

		return null;
	}
	public static Object findValueOfType(Collection collection, Class type) {
		if (isEmpty(collection))
			return null;
		Object value = null;
		Iterator it = collection.iterator();
		do {
			if (!it.hasNext())
				break;
			Object obj = it.next();
			if (type == null || type.isInstance(obj)) {
				if (value != null)
					return null;
				value = obj;
			}
		} while (true);
		return value;
	}
	public static Object findValueOfType(Collection collection, Class types[]) {
		if (isEmpty(collection) || ArrayUtils.isEmpty(types))
			return null;
		for (int i = 0; i < types.length; i++) {
			Object value = findValueOfType(collection, types[i]);
			if (value != null)
				return value;
		}

		return null;
	}

	public static boolean hasUniqueObject(Collection collection) {
		label0: {
			if (isEmpty(collection))
				return false;
			boolean hasCandidate = false;
			Object candidate = null;
			Object elem;
			label1: do {
				for (Iterator it = collection.iterator(); it.hasNext();) {
					elem = it.next();
					if (hasCandidate)
						continue label1;
					hasCandidate = true;
					candidate = elem;
				}

				break label0;
			} while (candidate == elem);
			return false;
		}
		return true;
	}
	 /**
     * 计算两个Collection对象的并集
     *
     * @param a
     * @param b
     * @return
     */
    public static Collection union(Collection a, Collection b) {
        return CollectionUtils.union(a, b);
    }

    /**
     * 计算两个Collection对象的交集
     *
     * @param a
     * @param b
     * @return
     */
    public static Collection intersection(Collection a, Collection b) {
        return CollectionUtils.intersection(a, b);
    }

    /**
     * @param a
     * @param b
     * @return
     */
    public static Collection disjunction(Collection a, Collection b) {
        return CollectionUtils.disjunction(a, b);
    }

    /**
     * 计算两个Collection对象相减
     *
     * @param a
     * @param b
     * @return
     */
    public static Collection subtract(Collection a, Collection b) {
        return CollectionUtils.subtract(a, b);
    }

    /**
     * 计算两个collection对象值是否相等
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean isEqualCollection(Collection a, Collection b) {
        return CollectionUtils.isEqualCollection(a, b);
    }
    public static void addAll(Collection collection, Iterator iterator) {
        CollectionUtils.addAll(collection, iterator);
    }

    public static void addAll(Collection collection, Enumeration enumeration) {
        CollectionUtils.addAll(collection, enumeration);
    }





	/**
	 * Check whether the given Enumeration contains the given element.
	 * @param enumeration the Enumeration to check
	 * @param element the element to look for
	 * @return <code>true</code> if found, <code>false</code> else
	 */
	public static boolean contains(Enumeration<?> enumeration, Object element) {
		if (enumeration != null) {
			while (enumeration.hasMoreElements()) {
				Object candidate = enumeration.nextElement();
				if (ObjectUtils.nullSafeEquals(candidate, element)) {
					return true;
				}
			}
		}
		return false;
	}
	public static boolean containsInstance(Collection<?> collection, Object element) {
		if (collection != null) {
			for (Object candidate : collection) {
				if (candidate == element) {
					return true;
				}
			}
		}
		return false;
	}
	
	public static <K, V> List<V> toList(Map<K, V> map) {
		List<V> resultList = new ArrayList<V>();
		for (Iterator<Map.Entry<K, V>> iterator = map.entrySet().iterator(); iterator.hasNext(); resultList
				.add(iterator.next().getValue()))
			;
		return resultList;
	}
	@SuppressWarnings("unchecked")
	public static  List<Object> toList(Object object){
		if(object instanceof Collection)
			return toList((Collection)object);
		if(object instanceof Map)
			return toList((Map)object);
		if(object instanceof Iterator)
			return toList((Iterator)object);
		if((object != null && object.getClass().isArray()))
			return asList(object);
		return null;
	}
	public static <E> List<E> toList(Enumeration<E> e){
	    ArrayList<E> resultList = new ArrayList<E>();
	    while (e.hasMoreElements())
	    	resultList.add(e.nextElement());
	    return resultList;
	}
	 /**
	   * Find the maximum element in a Collection, according to the natural
	   * ordering of the elements. This implementation iterates over the
	   * Collection, so it works in linear time.
	   *
	   * @param c the Collection to find the maximum element of
	   * @return the maximum element of c
	   * @exception NoSuchElementException if c is empty
	   * @exception ClassCastException if elements in c are not mutually comparable
	   * @exception NullPointerException if null.compareTo is called
	   */
	  public static <E> E max(Collection<E> c)
	  {
	    return max(c, null);
	  }
	  /**
	   * Find the maximum element in a Collection, according to a specified
	   * Comparator. This implementation iterates over the Collection, so it
	   * works in linear time.
	   *
	   * @param c the Collection to find the maximum element of
	   * @param order the Comparator to order the elements by, or null for natural
	   *        ordering
	   * @return the maximum element of c
	   * @throws NoSuchElementException if c is empty
	   * @throws ClassCastException if elements in c are not mutually comparable
	   * @throws NullPointerException if null is compared by natural ordering
	   *        (only possible when order is null)
	   */
	  public static <T> T max(Collection<T> c, Comparator<T> order)
	  {
	    Iterator<T> itr = c.iterator();
	    T max = itr.next(); // throws NoSuchElementException
	    int csize = c.size();
	    for (int i = 1; i < csize; i++)
	      {
	        T o = itr.next();
	        if (compare(max, o, order) < 0)
	          max = o;
	      }
	    return max;
	  }
	  /**
	   * Find the minimum element in a Collection, according to the natural
	   * ordering of the elements. This implementation iterates over the
	   * Collection, so it works in linear time.
	   *
	   * @param c the Collection to find the minimum element of
	   * @return the minimum element of c
	   * @throws NoSuchElementException if c is empty
	   * @throws ClassCastException if elements in c are not mutually comparable
	   * @throws NullPointerException if null.compareTo is called
	   */
	  public static <E> E min(Collection<E> c)
	  {
	    return min(c, null);
	  }
	  /**
	   * Find the minimum element in a Collection, according to a specified
	   * Comparator. This implementation iterates over the Collection, so it
	   * works in linear time.
	   *
	   * @param c the Collection to find the minimum element of
	   * @param order the Comparator to order the elements by, or null for natural
	   *        ordering
	   * @return the minimum element of c
	   * @throws NoSuchElementException if c is empty
	   * @throws ClassCastException if elements in c are not mutually comparable
	   * @throws NullPointerException if null is compared by natural ordering
	   *        (only possible when order is null)
	   */
	  public static <E> E min(Collection<E> c, Comparator<E> order)
	  {
	    Iterator<E> itr = c.iterator();
	    E min = itr.next();    // throws NoSuchElementExcception
	    int csize = c.size();
	    for (int i = 1; i < csize; i++)
	      {
	        E o = itr.next();
	        if (compare(min, o, order) > 0)
	          min = o;
	      }
	    return min;
	  }
	  /**
	   * Compare two objects with or without a Comparator. If c is null, uses the
	   * natural ordering. Slightly slower than doing it inline if the JVM isn't
	   * clever, but worth it for removing a duplicate of the search code.
	   * Note: This code is also used in Arrays (for sort as well as search).
	   */
	  static final <T> int compare(T o1, T o2, Comparator<T> c)
	  {
	    return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
	  }
	@SuppressWarnings("unchecked")
	public static <E> List<Object> asList(E... array) {
		return ArrayUtils.toList(array);
	}
	 /**
	   * Returns the starting index where the specified sublist first occurs
	   * in a larger list, or -1 if there is no matching position. If
	   * <code>target.size() &gt; source.size()</code>, this returns -1,
	   * otherwise this implementation uses brute force, checking for
	   * <code>source.sublist(i, i + target.size()).equals(target)</code>
	   * for all possible i.
	   *
	   * @param source the list to search
	   * @param target the sublist to search for
	   * @return the index where found, or -1
	   * @since 1.4
	   */
	  public static <E> int indexOfSubList(List<E> source, List<E> target)
	  {
	    int ssize = source.size();
	    for (int i = 0, j = target.size(); j <= ssize; i++, j++)
	      if (source.subList(i, j).equals(target))
	        return i;
	    return -1;
	  }
	  /**
	   * Returns the starting index where the specified sublist last occurs
	   * in a larger list, or -1 if there is no matching position. If
	   * <code>target.size() &gt; source.size()</code>, this returns -1,
	   * otherwise this implementation uses brute force, checking for
	   * <code>source.sublist(i, i + target.size()).equals(target)</code>
	   * for all possible i.
	   *
	   * @param source the list to search
	   * @param target the sublist to search for
	   * @return the index where found, or -1
	   * @since 1.4
	   */
	  public static <E>int lastIndexOfSubList(List<E> source, List<E> target)
	  {
	    int ssize = source.size();
	    for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
	      if (source.subList(i, j).equals(target))
	        return i;
	    return -1;
	  }
	  /**
	   * Returns an Enumeration over a collection. This allows interoperability
	   * with legacy APIs that require an Enumeration as input.
	   *
	   * @param c the Collection to iterate over
	   * @return an Enumeration backed by an Iterator over c
	   */
	  public static <E>Enumeration<E> toEnumeration(Collection<E> c)
	  {
	    final Iterator<E> i = c.iterator();
	    return new Enumeration<E>()
	    {
	      public final boolean hasMoreElements()
	      {
	        return i.hasNext();
	      }
	      public final E nextElement()
	      {
	        return i.next();
	      }
	    };
	  }  
	  static boolean containsAll(Collection<?> self, Collection<?> c) {
			checkNotNull(self);
			for (Object o : c) {
				if (!self.contains(o)) {
					return false;
				}
			}
			return true;
		}

		static <E> Collection<E> toCollection(Iterable<E> iterable) {
			return (iterable instanceof Collection) ? (Collection<E>) iterable
					: ListUtils.newArrayList(iterable);
		}

		private static void checkNotNull(Collection<?> collection) {
			if (collection == null)
				throw new NullPointerException();

		}
}
